{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "747f5473",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# API 키를 환경변수로 관리하기 위한 설정 파일\n",
    "from dotenv import load_dotenv\n",
    "\n",
    "# API 키 정보 로드\n",
    "load_dotenv()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cdc8d156",
   "metadata": {},
   "source": [
    "# YouTube 오디오\n",
    "\n",
    "YouTube 동영상을 기반으로 한 채팅이나 QA(질문과 답변) 애플리케이션 구축은 매우 관심이 높은 주제입니다.\n",
    "\n",
    "아래에서는 `YouTube url`에서 `동영상의 오디오`로, 그리고 `텍스트`로, 마지막으로 `채팅`으로 쉽게 전환하는 방법을 보여줍니다!\n",
    "\n",
    "`OpenAIWhisperParser`를 사용할 것이며, 이는 OpenAI Whisper API를 사용하여 오디오를 텍스트로 변환합니다.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3cd64261",
   "metadata": {},
   "source": [
    "`YoutubeAudioLoader`는 YouTube 오디오를 로드하는 데 사용되며, `GenericLoader`는 일반적인 문서 로딩 작업에 사용됩니다.\n",
    "\n",
    "또한, `OpenAIWhisperParser` 는 오디오 파일을 텍스트로 변환하는 데 사용되는 파서입니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "19cff3d2",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_community.document_loaders.blob_loaders.youtube_audio import (\n",
    "    YoutubeAudioLoader,\n",
    ")\n",
    "from langchain_community.document_loaders.generic import GenericLoader\n",
    "from langchain_community.document_loaders.parsers import OpenAIWhisperParser"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "466fc7c8",
   "metadata": {},
   "source": [
    "우리는 YouTube URL에 대한 오디오를 다운로드하기 위해 `yt_dlp`를 사용할 것입니다.\n",
    "\n",
    "다운로드한 오디오 파일을 분할하기 위해 (Whisper API의 25MB 파일 크기 제한을 준수하기 위해) `pydub`를 사용할 것입니다.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "051d3a56",
   "metadata": {},
   "source": [
    "이 문서는 `yt_dlp`, `pydub`, `librosa` 세 가지 Python 라이브러리를 설치하는 방법을 설명합니다. 각 라이브러리는 오디오 및 비디오 파일을 처리하는 데 사용됩니다. `yt_dlp`는 YouTube 동영상을 다운로드하기 위한 도구이며, `pydub`는 오디오 파일을 쉽게 조작할 수 있게 해주고, `librosa`는 오디오 분석 및 음악 정보 검색을 위한 라이브러리입니다. 이들은 Python에서 AI 및 머신러닝 프로젝트에 오디오 데이터를 사용할 때 필수적인 도구입니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ff3850e7",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 주석을 해제 후 설치를 진행합니다.\n",
    "# !pip install --upgrade --quiet yt_dlp\n",
    "# !pip install --upgrade --quiet pydub\n",
    "# !pip install --upgrade --quiet librosa"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7bd6b902",
   "metadata": {},
   "source": [
    "### YouTube url을 텍스트로 변환\n",
    "\n",
    "`YoutubeAudioLoader`를 사용하여 오디오 파일을 가져오거나 다운로드하세요.\n",
    "\n",
    "그런 다음, `OpenAIWhisperParser()`를 사용하여 그것들을 텍스트로 변환하세요.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "27365d26",
   "metadata": {},
   "source": [
    "이 코드는 YouTube 동영상의 오디오를 텍스트로 변환하는 과정을 구현합니다.\n",
    "\n",
    "먼저, `urls` 변수에 변환하고자 하는 YouTube 동영상의 URL들을 리스트 형태로 저장합니다.\n",
    "\n",
    "`save_dir` 변수에는 오디오 파일을 저장할 디렉토리 경로를 지정합니다. `local` 변수의 값에 따라, 로컬 환경에서 오디오를 텍스트로 변환할지, 아니면 다른 파서를 사용할지 결정합니다. `GenericLoader` 클래스는 `YoutubeAudioLoader`와 `OpenAIWhisperParser` 를 결합하여 동영상에서 오디오를 추출하고, 이를 텍스트로 변환하는 역할을 합니다.\n",
    "\n",
    "마지막으로, `load` 메소드를 호출하여 변환 과정을 실행하고 결과를 `docs` 변수에 저장합니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "2fc398ce",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[youtube] Extracting URL: https://youtu.be/fkxfGYPsmgc\n",
      "[youtube] fkxfGYPsmgc: Downloading webpage\n",
      "[youtube] fkxfGYPsmgc: Downloading ios player API JSON\n",
      "[youtube] fkxfGYPsmgc: Downloading android player API JSON\n",
      "[youtube] fkxfGYPsmgc: Downloading m3u8 information\n",
      "[info] fkxfGYPsmgc: Downloading 1 format(s): 140\n",
      "[download] Destination: ./youtube_audios//'공실 지옥'된 '지식산업센터'..현장 돌아보다 '경악' [뉴스.zip⧸MBC뉴스].m4a\n",
      "[download] 100% of    7.19MiB in 00:00:01 at 5.91MiB/s     \n",
      "[FixupM4a] Correcting container of \"./youtube_audios//'공실 지옥'된 '지식산업센터'..현장 돌아보다 '경악' [뉴스.zip⧸MBC뉴스].m4a\"\n",
      "[ExtractAudio] Not converting audio ./youtube_audios//'공실 지옥'된 '지식산업센터'..현장 돌아보다 '경악' [뉴스.zip⧸MBC뉴스].m4a; file is already in target format m4a\n",
      "Transcribing part 1!\n"
     ]
    }
   ],
   "source": [
    "# YouTube 동영상 URL\n",
    "urls = [\"https://youtu.be/fkxfGYPsmgc\"]\n",
    "\n",
    "# 오디오 파일을 저장할 디렉토리\n",
    "save_dir = \"./youtube_audios/\"\n",
    "\n",
    "# 동영상을 텍스트로 변환\n",
    "loader = GenericLoader(YoutubeAudioLoader(\n",
    "    urls, save_dir), OpenAIWhisperParser())\n",
    "docs = loader.load()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb065f93",
   "metadata": {},
   "source": [
    "이 코드는 `docs` 리스트의 첫 번째 문서에서 처음 500자까지의 페이지 내용을 추출합니다. `docs`는 문서 객체를 포함하는 리스트이며, 각 문서 객체는 페이지 내용에 접근할 수 있는 `page_content` 속성을 가지고 있습니다. 이를 통해 특정 문서의 내용 일부를 빠르게 확인하거나 처리할 수 있습니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "7aca2fe1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'최근 2, 3년 사이 서울 수도권 일대에 우후 쭉순 들어선 초대형 건물, 지식산업센터입니다. 그런데 이 건물들 좀 수상합니다. 지어진 지 1년이 지났지만 사람 구경조차 힘든 곳이 있는가 하면 상가도 사무실도 텅텅 비었습니다. 1년 전부터 이곳에 대해 관심을 가진 사람이 있습니다. 부동산 관련 개인 방송을 진행하는 개그맨 표영호 씨. 지난해 2월부터 지식산업센터를 저희 표영호TV에서 취재하면서 우리 경제의 큰 뇌관이 될 수 있다라고 여러분께 말씀을 드렸는데요. 이야 진짜 이건 너무 놀랍다. 아니 너무 놀라워서 믿어지지가 않아요. 매도하겠다고 하는 매물이 700개가 넘습니다. 6개월 전에 왔을 때도 여기가 다 비어있었는데 지금도 다 비어있네요. 1년 전보다 비교해서 나아진 게 없어요. 지금 여기 공실 상태는 오피스의 공실은 얼마나 됩니까? 지금 오피스는 공실률이 한 50% 되고 있습니다. 상가는 지금 몇 퍼센트 정도 공실이라고 봅니까? 상가는 거의 지하 1층 빼고는 거의 비어있다고 보시'"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 문서 목록을 반환하며, 이는 쉽게 보거나 파싱할 수 있습니다.\n",
    "docs[0].page_content[0:500]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "2d9f5bcb",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Document(page_content='최근 2, 3년 사이 서울 수도권 일대에 우후 쭉순 들어선 초대형 건물, 지식산업센터입니다. 그런데 이 건물들 좀 수상합니다. 지어진 지 1년이 지났지만 사람 구경조차 힘든 곳이 있는가 하면 상가도 사무실도 텅텅 비었습니다. 1년 전부터 이곳에 대해 관심을 가진 사람이 있습니다. 부동산 관련 개인 방송을 진행하는 개그맨 표영호 씨. 지난해 2월부터 지식산업센터를 저희 표영호TV에서 취재하면서 우리 경제의 큰 뇌관이 될 수 있다라고 여러분께 말씀을 드렸는데요. 이야 진짜 이건 너무 놀랍다. 아니 너무 놀라워서 믿어지지가 않아요. 매도하겠다고 하는 매물이 700개가 넘습니다. 6개월 전에 왔을 때도 여기가 다 비어있었는데 지금도 다 비어있네요. 1년 전보다 비교해서 나아진 게 없어요. 지금 여기 공실 상태는 오피스의 공실은 얼마나 됩니까? 지금 오피스는 공실률이 한 50% 되고 있습니다. 상가는 지금 몇 퍼센트 정도 공실이라고 봅니까? 상가는 거의 지하 1층 빼고는 거의 비어있다고 보시면 돼요. 표영호 씨가 지식산업센터에 관심을 갖게 된 이유가 있다고 합니다. 공실이 이렇게 어마어마한 상상을 초월할 정도로 많이 있는데도 지금도 또 인허가를 받아놓고 공사를 들어갈 곳도 300여 곳이 넘거든요. 이거를 아무도 말하지 않길래 다들 아파트 얘기만 하고 있길래 그러니까 그게 염려가 돼서 한 1년 반 전부터 제가 이 이야기를 했었죠. 부동산 프로젝트 파이낸싱, PF로 유동성 위기를 겪고 있는 태영건설이 결국 기업 구조 개선, 워크아웃을 신청했습니다. 최근 부도 위기를 맞았던 태영건설도 지식산업센터 건설에 적극 참여했습니다. 구로와 영등포를 비롯해 10곳의 시공을 직접 맡았습니다. 태영이 그러면서 이게 지사인이 분양하면 돈이 되는구나. 건설사만 하지 않고 시인도 같이 참여한 것 같아요. 대형 건설사들도 앞다퉈 지식산업센터를 짓기 시작했고 초대형 복합단지가 시장의 대세로 자리 잡았습니다. 그런데 지난해부터 상황이 급변했습니다. 수만평에 달하는 지식산업센터 부지들이 착공도 못한 채 처분을 기다리고 있습니다. 지금 지식산업센터에는 무슨 일이 벌어지고 있는 걸까요? 인근 부동산을 찾아 현재 이곳의 임대 상황을 알아보았습니다. 이렇게 일을 하는데 결과가 없으니까 맥받이는 거죠. 심지어 어떤 분들은 관리병원에 그냥 써야 되는데 그 정도로 심각하면 임대가 안 되니까. 매물은 쌓여가는데 바로 옆에 새로 입주한 지식산업센터의 물건까지 더해져 현재 임대 물건만 500개가 넘는다고 합니다. 그리고 여기 앞으로 추가로 들어올 게 4개나 더 있어요. 삼성전자가 있으니까 수혜가 충분하다고 분양을 했지만 막상 뚜껑을 열고 보니까 그만큼 기대하고는 너무 개리가 큰 거죠. 그런데 취재 과정에서 더 충격적인 이야기를 듣게 됐습니다. 실제로 지금 여기 산업단지 삼성전자를 중심으로 이런 지식산업센터가 한 20개 정도 현재 중공이 떨어졌거나 공사 중이거나 그런 것들이 한 20개 정도가 현재 있는 상황입니다. 그렇다 보니까 지금 수요 공급 안 맞아서 공급이 너무 많다 보니까 공실이 많이 발생하고 전체가 입주되기까지는 사실 기약이 없다고 봐야죠. 삼성 반도체 공장을 중심으로 반경 3km 이내에 무려 20개나 되는 지식산업센터가 있다는 것. 심지어 2년 전 입주를 시작했는데 입주율이 25%밖에 안 된 곳도 있습니다. 1층 상가는 아예 텅 비어 있습니다. 문제는 인근에 지식산업센터 건물이 계속 지어지고 있다는 것. 평택시가 건축허가를 계속 내주고 있다는 건데요. 어떻게 된 일일까. 이걸 저희가 예측하기가 너무나 어렵고 허가 조건에 맞으면 허가를 해줄 수밖에 없는 거죠. 지금도 들어오면 지금도 공급이 과잉이지만 들어오면 안 해줄 수가 없어요. 평택뿐 아니라 서울 수도권 일대가 다 비슷한 상황입니다. 현재 건축 중인 지식산업센터가 87개. 부지 메이프 미착공 상태인 지식산업센터도 300개가 넘습니다. 그리고 여기가 2개예요. 여기가 고산 신도시잖아요. 여기 하나가 또 올라가서 똑같이 지었어요. 여기 짓고 여기 짓고. 여기 밀락이 짓고. 똑같은 게 여기 또 있어요. 그리고 여기도 분양이 다 공식으로. 지식산업센터를 이렇게 많이 허락을 해준 이유가 뭐냐고. 지자체들이 건축허가를 많이 내준 이유가 있다고 합니다. 지자체 같은 경우는 산업체를 유치하는 게 굉장히 중요하잖아요. 세수 차원에서도 그렇고 고용 창출 부분에 있어서도 그러다 보니까 조례를 통해서 지식산업센터를 많이 만들 수 있는 구조가 됐거든요. 이거 지자체 입장에서도 불구하고 외부적으로 봤을 때도 우리가 일도 열심히 하고 그 지역을 또 발전을 시키고 지역의 생산소를 키울 수 있다고 보기 때문에 허가에 대해서 까다롭지가 않은 거죠. 기업 유치보다 사무실 유치에 더 적극적이었던 지방자치단체. 수도권 외곽의 지식산업센터는 미래가 더 암담합니다. 앞으로 여기 뭐 수요가 있겠어요. 대한민국에 그렇게 기업이 없잖아요. 사무실이. 싸게 1억씩 분양했다면 괜찮은데 3억 3천, 3억 4천 그렇게 분양하니까 시행사하고 시공사만 하는 거예요. 서민들 등껏 다 빼서 무섭게 들어가면 어쩌지 않고. MBC 뉴스 김성현입니다.', metadata={'source': \"youtube_audios/'공실 지옥'된 '지식산업센터'..현장 돌아보다 '경악' [뉴스.zip⧸MBC뉴스].m4a\", 'chunk': 0})"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "docs[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50a07248",
   "metadata": {},
   "source": [
    "### YouTube 동영상에서 질의-응답 챗봇 구축하기\n",
    "\n",
    "`Documents`를 주어진 상태에서, 우리는 쉽게 채팅 / 질문+답변 기능을 활성화할 수 있습니다.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b917112e",
   "metadata": {},
   "source": [
    "이 문서는 `langchain` 라이브러리와 그 커뮤니티 확장을 사용하여 질의응답(QA), 텍스트 분할, 벡터 저장소, 그리고 OpenAI와의 상호작용을 위한 코드를 보여줍니다. `RetrievalQA` 클래스는 질의응답 시스템을 구현하는 데 사용되며, `RecursiveCharacterTextSplitter`는 긴 텍스트를 처리하기 위한 텍스트 분할기입니다. `FAISS`는 고성능 벡터 검색을 위한 라이브러리를 활용하며, `ChatOpenAI`와 `OpenAIEmbeddings`는 OpenAI의 API를 활용하여 챗봇 기능과 텍스트 임베딩 기능을 제공합니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "fd6eb190",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.chains import RetrievalQA\n",
    "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
    "from langchain_community.vectorstores import FAISS\n",
    "from langchain_openai import ChatOpenAI, OpenAIEmbeddings"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6def8f26",
   "metadata": {},
   "source": [
    "이 함수는 여러 문서(`docs`)의 내용을 결합하여 하나의 문자열(`text`)로 만듭니다. 각 문서의 `page_content` 속성을 추출하여 리스트(`combined_docs`)에 저장한 후, 이 리스트의 모든 항목을 공백 문자로 연결합니다. 결과적으로, 모든 문서의 내용이 단일 문자열로 합쳐지게 됩니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "f8a710b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 문서 결합\n",
    "# docs의 각 문서에서 page_content를 추출하여 combined_docs에 저장합니다.\n",
    "combined_docs = [doc.page_content for doc in docs]\n",
    "text = \" \".join(combined_docs)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "014dfe64",
   "metadata": {},
   "source": [
    "`RecursiveCharacterTextSplitter` 클래스는 텍스트를 지정된 크기(`chunk_size`)의 조각으로 분할하고, 각 조각 사이에 일정량(`chunk_overlap`)의 중복을 허용하는 기능을 제공합니다. 이를 통해, 큰 텍스트 데이터를 처리할 때 각 조각이 서로 일부 정보를 공유하면서도 독립적으로 처리될 수 있도록 합니다. `split_text` 메소드는 주어진 텍스트(`text`)를 분할하고, 분할된 텍스트 조각들의 리스트를 반환합니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "940a2142",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 텍스트를 분할합니다.\n",
    "text_splitter = RecursiveCharacterTextSplitter(\n",
    "    chunk_size=1500, chunk_overlap=150)\n",
    "splits = text_splitter.split_text(text)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "727e5e1b",
   "metadata": {},
   "source": [
    "이 코드는 텍스트 데이터를 벡터로 변환하여 검색 가능한 색인을 구축하는 과정을 보여줍니다. `OpenAIEmbeddings` 클래스를 사용하여 임베딩을 생성하고, 이 임베딩을 `FAISS.from_texts` 메소드에 전달하여 `vectordb` 객체를 생성합니다. 이 객체는 텍스트 데이터의 벡터화된 표현을 저장하며, 이를 통해 효율적인 검색이 가능해집니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "78983f86",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 색인을 구축합니다.\n",
    "embeddings = OpenAIEmbeddings()\n",
    "vectordb = FAISS.from_texts(splits, embeddings)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6daf141",
   "metadata": {},
   "source": [
    "`RetrievalQA.from_chain_type` 함수는 `ChatOpenAI` 인스턴스를 사용하여 질의응답(QA) 체인을 구성합니다. 여기서 `model_name`은 사용할 모델을 지정하며, `temperature`는 생성된 응답의 다양성을 조절합니다. `chain_type`은 체인의 유형을 정의하고, `retriever`는 검색 엔진으로 사용됩니다. 이 예시에서는 `vectordb`를 검색 엔진으로 활용합니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "30a97644",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain.callbacks.base import BaseCallbackHandler\n",
    "\n",
    "\n",
    "class StreamCallback(BaseCallbackHandler):\n",
    "    def on_llm_new_token(self, token: str, **kwargs):\n",
    "        print(f\"{token}\", end=\"\", flush=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "51d1bc6f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# QA 체인 구축\n",
    "qa_chain = RetrievalQA.from_chain_type(\n",
    "    llm=ChatOpenAI(\n",
    "        model_name=\"gpt-4-turbo-preview\",\n",
    "        temperature=0,\n",
    "        streaming=True,\n",
    "        callbacks=[StreamCallback()],\n",
    "    ),\n",
    "    chain_type=\"stuff\",\n",
    "    retriever=vectordb.as_retriever(),\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "02e8ef1f",
   "metadata": {},
   "source": [
    "이 함수는 기계학습 모델의 학습 과정에서 역전파 단계 전에 기울기를 0으로 초기화하는 이유를 질의하는 예제입니다. `qa_chain.invokr({\"query\": query})`는 주어진 질문(`query`)에 대한 답변을 실행하는 함수입니다. 이 과정은 모델이 새로운 데이터 포인트에 대해 학습할 때 이전 단계의 기울기가 누적되지 않도록 하기 위해 필요합니다.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "232c0cc8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "지식산업센터 공실율의 가장 큰 원인은 공급과잉입니다. 삼성 반도체 공장을 중심으로 한 지역에만 무려 20개의 지식산업센터가 존재하며, 이 중 많은 수가 입주율이 낮거나 공사 중이거나 착공조차 되지 않은 상태입니다. 이러한 과잉 공급은 수요와 맞지 않아 공실이 많이 발생하게 되었습니다. 또한, 지자체들이 세수 증대와 고용 창출을 목적으로 지식산업센터 건설에 대한 건축 허가를 쉽게 내주었기 때문에, 이러한 공급 과잉 현상이 더욱 심화되었습니다."
     ]
    }
   ],
   "source": [
    "# 질문을 하세요!\n",
    "query = \"지식산업센터 공실율의 가장 큰 원인은 무엇인가요?\"\n",
    "answer = qa_chain.invoke({\"query\": query})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "6ed96ddb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "삼성전자 인근 지식산업센터의 공실율은 상당히 높은 상황입니다. 구체적으로 언급된 공실율은 없지만, 일부 지식산업센터의 경우 입주율이 25%밖에 되지 않는 곳도 있으며, 1층 상가는 아예 비어 있는 상황입니다. 이는 공급이 수요를 초과하여 발생한 문제로, 전체가 입주되기까지는 기약이 없는 상태로 보입니다."
     ]
    }
   ],
   "source": [
    "# 질문을 하세요!\n",
    "query = \"삼성전자 인근 지식산업센터의 공실율이 어떻게 되나요?\"\n",
    "answer = qa_chain.invoke({\"query\": query})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2667e4f5",
   "metadata": {},
   "source": [
    "> 태영건설과 공실율\n",
    "\n",
    "https://youtu.be/fkxfGYPsmgc?si=EaUgz_mS-gxMg1dG&t=123\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "8c3f36e4",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "서울 수도권 일대에 최근 2, 3년 사이 대규모로 들어선 지식산업센터들이 공실 문제에 직면해 있습니다. 이러한 상황은 태영건설과도 밀접한 관련이 있습니다. 태영건설은 부동산 프로젝트 파이낸싱(PF)으로 인한 유동성 위기를 겪으며 기업 구조 개선, 즉 워크아웃을 신청했습니다. 이 회사는 지식산업센터 건설에 적극적으로 참여했으며, 구로와 영등포를 포함한 10곳의 지식산업센터 시공을 직접 맡았습니다.\n",
      "\n",
      "태영건설의 사례는 지식산업센터 건설 붐과 그로 인한 공실 문제의 한 단면을 보여줍니다. 지식산업센터 건설이 활발히 이루어지면서 대형 건설사들도 이 시장에 뛰어들었고, 이로 인해 초대형 복합단지가 시장의 대세로 자리 잡았습니다. 그러나 지난해부터 상황이 급변하면서 수만 평에 달하는 지식산업센터 부지들이 착공도 못한 채 처분을 기다리는 상황에 이르렀습니다.\n",
      "\n",
      "이러한 공실 문제는 태영건설뿐만 아니라 다른 건설사들에게도 영향을 미치고 있으며, 전반적인 부동산 시장에도 부정적인 영향을 주고 있습니다. 공급 과잉으로 인한 공실률 증가는 지식산업센터의 가치 하락을 초래하고, 이는 결국 건설사들의 수익성 악화로 이어집니다. 태영건설의 경우, 지식산업센터 건설에 대한 적극적인 참여가 유동성 위기의 한 원인으로 작용했을 가능성이 있으며, 이는 다른 건설사들에게도 경고의 메시지로 작용할 수 있습니다."
     ]
    }
   ],
   "source": [
    "# 질문을 하세요!\n",
    "query = \"공실율과 태영과의 연관성에 대해 설명해 주세요.\"\n",
    "answer = qa_chain.invoke({\"query\": query})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8b276167",
   "metadata": {},
   "source": [
    "> 관련 영상\n",
    "\n",
    "https://youtu.be/fkxfGYPsmgc?si=6nx2qp4sFTmOWGJR&t=367\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "a5c655c2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "현재 건축 중인 지식산업센터는 87개이고, 부지 메이프 미착공 상태인 지식산업센터는 300개가 넘습니다."
     ]
    }
   ],
   "source": [
    "# 질문을 하세요!\n",
    "query = \"현재 건축중인 지식산업센터와 미준공인 지식산업센터의 수는 어떻게 되나요?\"\n",
    "answer = qa_chain.invoke({\"query\": query})"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "py-test",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
